/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
    
package be.vdabantwerpen.gow.dao;
    
import be.vdabantwerpen.gow.entities.Post;
import be.vdabantwerpen.gow.entities.Score;
import be.vdabantwerpen.gow.entities.GOWUser;
import com.google.appengine.api.datastore.DatastoreService;
import com.google.appengine.api.datastore.DatastoreServiceFactory;
import com.google.appengine.api.datastore.Entity;
import com.google.appengine.api.datastore.EntityNotFoundException;
import com.google.appengine.api.datastore.Key;
import com.google.appengine.api.datastore.KeyFactory;
import com.google.appengine.api.datastore.PreparedQuery;
import com.google.appengine.api.datastore.Query;
import com.google.appengine.repackaged.org.joda.time.DateTime;
import java.util.ArrayList;
import java.util.List;

/**
 *
 * @author Tim.VandenLangenberg
 * @version 1.0
 */
public class ScoreDAOImpl implements ScoreDAO {
    private final DatastoreService datastore = 
            DatastoreServiceFactory.getDatastoreService();
    private final PostDAO postDAO = new PostDAOImpl();
    private final UserDAO userDAO = new UserDAOImpl();
    
    @Override
    public void create(Score score){
        Entity scoreEntity = toEntity(score);
        datastore.put(scoreEntity);
    }
    
    @Override
    public Score read(int scoreId){
        try {
            Key key = KeyFactory.createKey("Score", scoreId);
            return toScore(datastore.get(key));
        }
        catch(EntityNotFoundException enfe){
            return null;
        }
    }
    
    @Override
    public void update(Score score){
        Entity e = toEntity(score);
        datastore.put(e);
    }
    
    @Override
    public void delete(Score score){
        datastore.delete(toEntity(score).getKey());
    }
    
    @Override
    public List<Score> findScoresByUser(GOWUser user){
        List<Score> scores = new ArrayList();
        Query q = new Query("Score");
        PreparedQuery pq = datastore.prepare(q);
        for(Entity entity : pq.asIterable()){
            Score score = toScore(entity);
            if(score.getUser().equals(user)){
                scores.add(score);
            }
        }
        return scores;
    }
    
    @Override
    public List<Score> findScoresbyPost(Post post){
        List<Score> scores = new ArrayList();
        Query q = new Query("Score");
        PreparedQuery pq = datastore.prepare(q);
        for(Entity entity : pq.asIterable()){
            Score score = toScore(entity);
            if(score.getPost().equals(post)){
                scores.add(score);
            }
        }
        return scores;
    }
    
    private Score toScore(Entity entity){
        Post post; 
        if(entity.getProperty("post") == null){
            post = null;
        }
        else { 
            post = postDAO.read(Integer.valueOf(entity.getProperty("post").toString()));
        }
        DateTime dateTime; 
        if(entity.getProperty("dateTime") == null){
            dateTime = null;
        }
        else {
            dateTime = DateTime.parse(entity.getProperty("dateTime").toString());
        }
        int value = Integer.valueOf(entity.getProperty("value").toString());
        GOWUser user;
        if(entity.getProperty("user") == null){
            user = null;
        }
        else { 
            user = userDAO.read(Integer.valueOf(entity.getProperty("user").toString()));
        }
        return new Score(post, dateTime, value, user);
    }
    
    private Entity toEntity(Score score){
        Entity entity = new Entity("Score", score.hashCode());
        if(score.getPost() != null){
            entity.setProperty("post", score.getPost().hashCode());
        }
        if(score.getDateTime() != null){
            entity.setProperty("dateTime", score.getDateTime().toString());
        }
        entity.setProperty("value", score.getValue());
        if(score.getUser() != null){
            entity.setProperty("user", score.getUser().getUserId());
        }
        return entity;
    }
    
}
